Simulation programs are frequently used for testing integrated circuits. Integrated circuit production is characterized by high initial costs for the production of the first “copy” followed by low marginal costs for each successive copy. Testing of a design for an integrated circuit prior to production is almost imperative. There are simulation tools provided solely for testing integrated circuit designs.
One of the most popular simulation tools is known as Verilog™. Integrated circuit testing is achieved in Verilog™ through completion of various tasks. Verilog™ tasks are executed by calling the task from a calling statement in a calling thread. After execution of the Verilog™ task, execution is returned to the next statement in the calling thread. In many cases, multi-threaded programming is needed to test multiple features of a design in one simulation run. Multi-threaded programming involves multiple flows of instructions, each of which can include a task call to the same task. Calls to the same task are carried out serially.
One drawback of multi-threaded programming in the Verilog™ context is that there is no way to control serial execution of the same task calls from different threads, due to the concurrent nature of Verilog™. An arbitration scheme must be in place such that any task call from one thread is not be carried out until the previous task call to an identical task is finished.
Although each task call will start a unique procedure process, all the procedure processes from the same task will share the same parameters and local variables. These procedure processes have the potential to collide with each other and produce unexpected and undesired results. Thus, the arbiter must also address these issues.
An existing method for resolving this problem is to put each of the threads in a separate module, wherein each module has its own task. In the foregoing manner, a task call procedure belongs to the module instance where it is declared. Two identical tasks in two different modules will never collide with each other since the tasks do not share any parameters and local variables. Arbitration on the task calls is achieved by control permission on the task calls in the different modules. However, the foregoing is complex. For example, in 32 thread testing, 32 modules need to be created.
Accordingly, it would be beneficial if a simpler scheme for handling conflicts between task calls in multiple threads was provided.
Further limitations and disadvantages of conventional and traditional approaches will become apparent to one of skill in the art, through comparison of such systems with embodiments presented in the remainder of the present application with references to the drawings.